package Socket;/*
 * Copyright (c) 2010-2018 Nathan Rajlich
 *
 *  Permission is hereby granted, free of charge, to any person
 *  obtaining a copy of this software and associated documentation
 *  files (the "Software"), to deal in the Software without
 *  restriction, including without limitation the rights to use,
 *  copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following
 *  conditions:
 *
 *  The above copyright notice and this permission notice shall be
 *  included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *  OTHER DEALINGS IN THE SOFTWARE.
 */

import android.util.Log;

import org.greenrobot.eventbus.EventBus;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.math.BigDecimal;
import java.net.URI;
import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import Been.been_fuifang_event;
import Been.DuanwangMessage;


//监视的websocket客户端

/**
 * This example demonstrates how to create a websocket connection to a server. Only the most important callbacks are overloaded.
 */
public class PlayBackClient extends WebSocketClient {
    private List<been_fuifang_event> planes = new ArrayList<>();  //?
    private int plane_num = 0; //?
    private long currentTime; //?
    private int frame_num = 0;  //?
    private List<been_fuifang_event> cur_pos = new ArrayList<>();
    private boolean isrunning = true;//?
    private PlayBackClient ws; // ?
    private static long dt;//时间差
    private int p_num = 0;
    static PlayBackClient _this;
    private Calendar startCalendar;
    private int startYear, startMonth, startDay, startHour, startMinute, startSecnod;
    private long shijianchuo, ts, height; //???seq什么？？
    private double lat, lng, speed, course;
    private String id = "";
    private long nowTimeSpan;
    private List<been_fuifang_event> returnpoints = new ArrayList<>();
    private List<been_fuifang_event> points = new ArrayList<>();
    static PlayBackClient c;
    private static int yunxing;


    public PlayBackClient(URI serverURI) {
        super(serverURI);
        this.ws = this;
        _this = this;
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        send(id);
        System.out.println("opened connection");
        //c.send(id);
//        if (planes!=null)
//            planes.clear();
        // if you plan to refuse connection based on ip or httpfields overload: onWebsocketHandshakeReceivedAsClient
    }

    public void reconnect(PlayBackClient duanwang) {
        duanwang.connect();
    }



    @Override
    public void onMessage(String message) {
        System.out.println("received: " + message);
       // if(message.equals("ok")){
            EventBus.getDefault().post(new been_fuifang_event(111,111.0,111.0,111,111));
      //  }

    }

    public void onMessage(ByteBuffer bytes) {

        Log.e("数据: ",String.valueOf(bytes.array().length));
//		ExampleClient.this.run();
        if (bytes.hasArray()) {
            byte[] sizes = bytes.array();

//            byte[] s1 = Arrays.copyOfRange(sizes, 0, 1);  //第一个字节
//            int i1 = (int) s1[0];//表示后面的id占几个字节
//            i1 = i1<0?i1+256:i1;
//
//            byte[] s11 = Arrays.copyOfRange(sizes, 1, i1 + 1);//id
            int i1 = 0;
            while (i1 < sizes.length) {


                byte[] s22 = Arrays.copyOfRange(sizes, i1, i1+1);//第三部分 type
                i1++;
                //String carid = new String(s11);//车的id

                int b1 = (int) s22[0];
                b1 = b1 < 0 ? b1 + 256 : b1;
                int type = b1 / 8;//传来数据的type（0 1 2 表示有经纬度  2 3 无速度  4只有电压和速度)
                if (type == 0 || type == 1 || type == 2) {
                    byte[] s33 = Arrays.copyOfRange(sizes, i1, i1+1);//第四部分
                    i1++;
                    byte[] s44 = Arrays.copyOfRange(sizes, i1, i1+1);//第五部分
                    i1++;
                    byte[] s55 = Arrays.copyOfRange(sizes, i1, i1+1);//第六部分
                    i1++;
                    byte[] s66 = Arrays.copyOfRange(sizes, i1, i1+1);//第七部分
                    i1++;
                    byte[] s77 = Arrays.copyOfRange(sizes, i1, i1+1);//第八部分
                    i1++;
                    int b2 = (int) s33[0];
                    b2 = b2 < 0 ? b2 + 256 : b2;
                    int b3 = (int) s44[0];
                    b3 = b3 < 0 ? b3 + 256 : b3;
                    int b4 = (int) s55[0];
                    b4 = b4 < 0 ? b4 + 256 : b4;
                    int b5 = (int) s66[0];
                    b5 = b5 < 0 ? b5 + 256 : b5;
                    int b6 = (int) s77[0];
                    b6 = b6 < 0 ? b6 + 256 : b6;
                    int b7 = -1;

                    long lngg = (b1 % 8) * (long) Math.pow(2, 19) + b2 * (long) Math.pow(2, 11) + b3 * 8 + b4 / 32;
                    long latt = (b4 % 32) * (long) Math.pow(2, 16) + b5 * 256 + b6;
                    float lng = (float) lngg / 10000;
                    float lat = (float) latt / 10000;
                    lng = lng > 180 ? 180 - lng : lng;
                    lat = lat > 180 ? 180 - lat : lat;


                    if (type == 0) {
                        //有速度
                        byte[] s88 = Arrays.copyOfRange(sizes, i1, i1+1);//第八部分
                        i1++;
                        b7 = (int) s88[0];
                        b7 = b7 < 0 ? b7 + 256 : b7;


                    }else {
                        i1++;
                    }

                    //处理时间  用电压的值代替时间
                    byte[] btime1 = Arrays.copyOfRange(sizes, i1, i1+1);//第八部分
                    i1++;
                    int time1 = (int) btime1[0];
                    time1 = time1 < 0 ? time1 + 256 : time1;

                    byte[] btime2 = Arrays.copyOfRange(sizes, i1, i1+1);//第八部分
                    i1++;
                    int time2 = (int) btime2[0];
                    time2 = time2 < 0 ? time2 + 256 : time2;

                    byte[] btime3 = Arrays.copyOfRange(sizes, i1, i1+1);//第八部分
                    i1++;
                    int time3 = (int) btime3[0];
                    time3 = time3 < 0 ? time3 + 256 : time3;

                    byte[] btime4 = Arrays.copyOfRange(sizes, i1, i1+1);//第八部分
                    i1++;
                    int time4 = (int) btime4[0];
                    time4 = time4 < 0 ? time4 + 256 : time4;

                    long shijian = time1 * (long) Math.pow(2, 24)
                            + time2 * (long) Math.pow(2, 16)
                            + time3 * (long) Math.pow(2, 8)
                            + time4;


                    EventBus.getDefault().post(new been_fuifang_event(type, lng, lat, shijian, b7));


                }//type为 3及之后的  无经纬度都不传
//                else {
//
//                    double dianya = b1 % 64;
//                    byte[] s33 = Arrays.copyOfRange(sizes, i1, i1+1);//第四部分
//                    i1++;
//                    int speed = (int) s33[0];
//                    speed = speed < 0 ? speed + 256 : speed;
//                    //EventBus.getDefault().post(new been_fuifang_event(type,999.0,999.0,dianya,speed));
//                }


            }
        }
    }

    public List<been_fuifang_event> consumer_point() {

        List<been_fuifang_event> carsbeens = new ArrayList<>();
        return carsbeens;
    }


    //之前那个有点问题TimeUtil，返回数据不准确
    public long getshijianchuo(String tsStr) {
        //获取时间戳的工具类
        DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        long epoch = 0;
        //1361325960
        try {
            epoch = df.parse(tsStr).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return epoch;
    }

//    public double get_angle(Databeen before,Databeen after){
//	    double e = after.lng - before.lng;
//	    double n = after.lat - before.lat;
//	    e = norm_lng(e);
//	    return Math.atan2(e,n) * (180 / Math.PI);
//    }
//    public List<Planesbeen> consumer_point(){
//	    if (now_ts() == 0){
//	        return null;
//        }
//        long now = (new Date()).getTime();
//        long nettime = this.now_ts() * 1000; //单位为毫秒
//        long dt1 = now  - nettime;
//        if (dt!=0){
//            if (Math.abs(dt1 - dt) > 5000){
//                dt = dt1;
//            }
//            now -= dt;
////            Log.i("777", "修改后的值: " + now + "  this.dt的值："+ this.dt  + "  dt1的值:" + dt1 + " dt的值：" + dt);
//        }else {
//            dt = dt1;
//            now = nettime;
//        }
//        List<Planesbeen> points = new ArrayList<>();
//        if (planes != null){
//            for (int i = 0 ;i<planes.size();i++){
//                Planesbeen plane = planes.get(i);
//                if ( (plane.last_move  == now) || (now == 0)){
//                    continue;
//                }
//                if (plane.data != null && plane.data.size() != 0 ){
//                    Databeen last_point = plane.data.get(plane.data.size() - 1);
//                    if ( now / 1000.0 - last_point.ts > 150){
//                        Planesbeen planesbeen = new Planesbeen();
//                        planesbeen.id = plane.id;
//                        planesbeen.lng = 200;
//                        planesbeen.lat = 200;
//                        points.add(planesbeen);
//                        this.planes.remove(i);
//                        --plane_num;
//                        continue;
//                    }
//                    int old_t = plane.t;
//
////                    /*
//                    if ( ((last_point.seq - plane.data.get(plane.t).seq) / 1000.0 ) > (plane.interval * 2 +1 )){
//                        if (plane.data.size()> (plane.t +1))
//                        while (plane.data.size()> (plane.t +1) &&  plane.data.get(plane.t).seq != last_point.seq && plane.data.get(plane.t +1)!= null && plane.data.get(plane.t + 1).seq != last_point.seq){
//                            if (now - plane.data.get(plane.t +1).seq < (plane.interval + 2) * 1000){
//                                break;
//                            }
//                            ++ plane.t;
//                            planes.set(i,plane);
//                        }
//
//                    }
//                    if (plane.data.size()>plane.t+1){
//                        while (plane.data.size()>plane.t+1 && plane.data.get(plane.t+1) != null && plane.data.get(plane.t +1).ts < now / 1000.0 - plane.interval - 10){
//                            ++plane.t;
//                            planes.set(i,plane);
//
//                        }
//                    }
//
//                    if (plane.data.size()>plane.t +2){
//                        if (old_t == plane.t && plane.last_move!=0 && plane.data.get(plane.t +2)!= null && (now - plane.data.get(plane.t).last_move) / 1000.0 > (plane.data.get(plane.t +1).ts - plane.data.get(plane.t).ts)){
//                            ++plane.t;
//                            planes.set(i,plane);
//                        }
//                    }
////                    */
//
//
//                    int j ;
//                    for (j= 0 ;j<cur_pos.size();j++){
//                        Planesbeen planesbeen = cur_pos.get(j);
//                        if (planesbeen.id.equals(plane.id)){
//                            break;
//                        }
//                    }
//                    if (j == cur_pos.size()){
//                        Planesbeen planesbeen = new Planesbeen();
//                        planesbeen.id = plane.id;
//                        planesbeen.data = new ArrayList<Databeen>();
//                        planesbeen.data.add(plane.data.get(0));
//                        planesbeen.angle = 998; //本应该赋初值为null，可是float型变量，无法赋值为null
//                        cur_pos.add(planesbeen);
//                    }
//
//                    if (last_point.speed < 70){
//                        if (old_t != plane.t || plane.last_move == 0){
//                            if (plane.data.size()>plane.t){
//                                plane.data.get(plane.t).last_move = now;
//                                planes.set(i,plane);
//                                for (int k = 0;k <cur_pos.size();k ++){
//                                    Planesbeen planesbeen = cur_pos.get(k);
//                                    if (planesbeen.id.equals(plane.id)){
//                                        double old_angle = planesbeen.angle;
//                                        planesbeen.lng = plane.data.get(plane.t).lng;
//                                        planesbeen.lat = plane.data.get(plane.t).lat;
//                                        if (plane.data!=null && plane.data.size() >plane.t+1){
//                                            if (plane.data.size()> plane.t+1 && plane.data.get(plane.t+1)!= null ){
//                                                planesbeen.angle = this.get_angle(plane.data.get(plane.t),plane.data.get(plane.t+1));
//                                            }
//                                        }
//                                        else {
//                                            planesbeen.angle = 998;
//                                        }
////                                        for (int m = old_t;m<plane.t;m++){
////                                            Databeen databeen =  plane.data.get(m);
////                                            databeen.last_move = 0;  //这里本应该将databeen这个对象，除了经纬度之外的属性删除，但是目前只有这种方式。
////                                            databeen.speed = 0;
////                                            databeen.ts = 0;
////                                            databeen.seq = 0;
////                                            databeen.course = 0;
////                                            databeen.height = 0;
////                                            plane.data.set(m,databeen);//更新data内容
////                                        }
//                                        cur_pos.set(k,planesbeen);
//                                    }
//                                }
//                            }
//
//
//                        }else {
//                            if (plane.data!=null && plane.data.size()>plane.t +1)
//                            if (plane.data.get(plane.t +1)!=null){
//                                for (int n =0 ;n<cur_pos.size();n++){
//                                    Planesbeen planesbeen = cur_pos.get(n);
//                                    if (planesbeen.id.equals(plane.id)){
//                                        if (planesbeen.angle== 998){
//                                            planesbeen.angle = this.get_angle(plane.data.get(plane.t), plane.data.get(plane.t + 1));
//                                            cur_pos.set(n,planesbeen);
//                                        }
//                                        //看到这里了！！！！
//                                        Log.i("777", "for循环里面的now2: " + now);
//                                        //我去！！坑惨了自己1000.0
//                                        if ((plane.data.get(plane.t + 1).ts - plane.data.get(plane.t).ts) !=0){
//                                            double dr = (now - plane.data.get(plane.t).last_move) / 1000.0 / (plane.data.get(plane.t + 1).ts - plane.data.get(plane.t).ts);
//                                            Log.i("555", "now - last_move: "  + (now - plane.data.get(plane.t).last_move));
//                                            Log.i("555", "now: " + now); //52秒
//                                            Log.i("555", "last_move: "+plane.data.get(plane.t).last_move); //49秒
//                                            Log.i("555", "ts: " + (plane.data.get(plane.t + 1).ts));
//                                            Log.i("555", "ts1: "+ (plane.data.get(plane.t).ts));
//                                            Log.i("555", "ts - ts1: " + (plane.data.get(plane.t + 1).ts - plane.data.get(plane.t).ts));
//                                            Log.i("555", "dr: " + dr);
//                                            if (dr<= 1.0){
//                                                planesbeen.lng = plane.data.get(plane.t).lng + (plane.data.get(plane.t + 1).lng - plane.data.get(plane.t).lng)* dr;
//                                                planesbeen.lat = plane.data.get(plane.t).lat + (plane.data.get(plane.t + 1).lat - plane.data.get(plane.t).lat)* dr;
//                                                cur_pos.set(n,planesbeen);
//                                                Log.i("555", "consumer_point: dr "+ dr + " lat: "+ planesbeen.lat + " lng： " + planesbeen.lng);
//                                            }else {
//                                                continue;
//                                            }
//                                        }
//
//
//                                    }
//
//                                }
//                            }
//                        }
//                    }else {
//                        if (plane.data!=null && plane.data.size()>plane.t)
//                        if (old_t != plane.t || plane.last_move == 0){
//                            plane.data.get(plane.t).last_move = now;
//                            planes.set(i,plane);
//                            for (int m = 0;m<cur_pos.size();m++){
//                                Planesbeen planesbeen = cur_pos.get(m);
//                                if (planesbeen.id.equals(plane.id)){
//                                    planesbeen.lng = plane.data.get(plane.t).lng;
//                                    planesbeen.lat = plane.data.get(plane.t).lat;
//                                    plane.data.get(plane.t).last_move = now;
//                                    planes.set(i,plane);
//                                    if (plane.data.size()>plane.t +1 && plane.data.get(plane.t + 1)!= null){
//                                        plane.halfspeed = false;
//                                        plane.dlng = (plane.data.get(plane.t + 1).lng - planesbeen.lng) / ((plane.data.get(plane.t +1).ts - plane.data.get(plane.t).ts)* 1.0);
//                                        plane.dlat = (plane.data.get(plane.t + 1).lat - planesbeen.lat) / ((plane.data.get(plane.t +1).ts - plane.data.get(plane.t).ts)* 1.0);
//                                        planes.set(i,plane);
//                                        Databeen databeen = new Databeen();
//                                        databeen.id = planesbeen.id;
//                                        databeen.lat = planesbeen.lat;
//                                        databeen.lng = planesbeen.lng;
//                                        planesbeen.angle = this.get_angle(databeen, plane.data.get(plane.t + 1));
//                                    }else if (plane.dlng != 0.0){
//                                        plane.dlng = plane.dlng * 0.9;
//                                        plane.dlat = plane.dlat * 0.9;
//                                        plane.halfspeed = true;
//                                        planes.set(i,plane);
//                                    }
//                                    planesbeen.redraw = true;
//                                    cur_pos.set(m,planesbeen);
//                                }
//                            }
//                        }else {
//                            if ((plane.dlng != 0 || plane.halfspeed) && plane.data.size()> plane.t +1 && plane.data.get(plane.t + 1)!= null){
//                                plane.halfspeed =false;
//                                plane.dlng = (plane.data.get(plane.t +1).lng - plane.data.get(plane.t).lng) / ((plane.data.get(plane.t +1).ts - plane.data.get(plane.t).ts)* 1.0);
//                                plane.dlat = (plane.data.get(plane.t +1).lat - plane.data.get(plane.t).lat) / ((plane.data.get(plane.t + 1).ts - plane.data.get(plane.t).ts)* 1.0);
//                                planes.set(i,plane);
//                                for (int m = 0;m<cur_pos.size();m++){
//                                    Planesbeen planesbeen = cur_pos.get(m);
//                                    if (planesbeen.id.equals(plane.id)){
//                                        planesbeen.angle = this.get_angle(plane.data.get(plane.t), plane.data.get(plane.t +1));
//                                        cur_pos.set(m,planesbeen);
//                                    }
//                                }
//                            }
//                            Log.i("777", "for循环里面的now3: " + now);
//                            if (now - plane.data.get(plane.t).last_move > 120000){
//                                continue;
//                            }else if (plane.dlng!=0.0){
//                                for (int m = 0;m<cur_pos.size();m++){
//                                    Planesbeen planesbeen = cur_pos.get(m);
//                                    if (planesbeen.id.equals(plane.id)){
//                                        planesbeen.lng = planesbeen.lng + (plane.dlng * (now - plane.last_move) / 1000.0);
//                                        planesbeen.lat = planesbeen.lat + (plane.dlat * (now - plane.last_move) / 1000.0);
//                                        cur_pos.set(m,planesbeen);
//                                    }
//                                }
//                            }
//                            for (int m = 0;m<cur_pos.size();m++){
//                                Planesbeen planesbeen = cur_pos.get(m);
//                                if (planesbeen.id.equals(plane.id)){
//                                    planesbeen.redraw = false;
//                                    cur_pos.set(m,planesbeen);
//                                }
//                            }
//
//                        }
//                    }
//                    Log.i("777", "for循环里面的now4: " + now);
//                    plane.last_move = now;  //last_move的赋值操作没有进行
//                    Log.i("777", "for循环里面的now5: " + now);
//                    planes.set(i,plane);
//                    for (int m = 0;m<cur_pos.size();m++){
//                        Planesbeen planesbeen = cur_pos.get(m);
//                        if (planesbeen.id.equals(plane.id)){
//                            planesbeen.speed = last_point.speed;
//                            planesbeen.course = last_point.course;
//                            planesbeen.height = last_point.height;
//                            planesbeen.slng = last_point.lng;
//                            planesbeen.slat = last_point.lat;
//                            planesbeen.ts = last_point.ts;
//                            cur_pos.set(m,planesbeen);
//                            //2018-08-30写到这里了！！！
//                            points.add(planesbeen);
//
//                        }
//                    }
//                }
//            }
//        }
////        if (points!=null)
////        Log.i("消费了", "consumer_point: " + points.size());
//        return points;
//    }

//    public long initTime(){
//        String nowTime = TommorrowDay(0);
//        nowTimeSpan = TimeUtil.string2Millis(nowTime);
//        return nowTimeSpan;
//    }

    /**
     * 天数加一
     */
    public static String TommorrowDay(int data) {
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMMddHHmmss");
        Date beginDate = new Date();
        Calendar date = Calendar.getInstance();
        date.setTime(beginDate);
        date.set(Calendar.DATE, date.get(Calendar.DATE) + data);
        Log.i("date", String.valueOf(date.get(Calendar.DATE) + data));
        // Date endDate = dft.parse(dft.format(date.getTime()));
        String time = dft.format(date.getTime());
        return time;
    }

    public boolean panduanjinwei(double jinwei, int flag) {
        if (flag == 1) {
            //判断纬度
            if (jinwei >= -90 && jinwei <= 90) {
                return true;
            } else {
                return false;
            }
        }
        if (flag == 2) {
            //判断经度
            if (jinwei >= -180 && jinwei <= 180) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }


    public double formatlnglat(long ll) {
        long templng = ll / 2;
//	    int _dd = Integer.valueOf(String.valueOf(Math.floor(templng / getcifang(10,6))));

//        double dInput = templng / getcifang(10,6);
        double dInput = templng * 1.0 / 1e6;
        int longPart = (int) dInput;
        BigDecimal bigDecimal = new BigDecimal(Double.toString(dInput));
        BigDecimal bigDecimalLongPart = new BigDecimal(Double.toString(longPart));
        double dPoint = bigDecimal.subtract(bigDecimalLongPart).doubleValue();
        System.out.println("整数部分为:" + longPart + "\n" + "小数部分为: " + dPoint);
        int _dd = longPart;
        double _mm = (templng % 1e6) / 1e4 / 60.0;
        return ll % 2 == 0 ? (_dd + _mm) : (_dd + _mm) * -1;
    }

    public long getcifang(long a, int b) {
        for (int i = 0; i < b - 1; i++) {
            a = a * 10;
        }
        return a;
    }

    public static String byte2HexString(byte[] bytes) {
        String hex = "";
        if (bytes != null) {
            for (Byte b : bytes) {
                hex += String.format("%02X", b.intValue() & 0xFF);
            }
        }
        return hex;
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        // The codecodes are documented in class org.java_websocket.framing.CloseFrame
        System.out.println("Connection closed by " + (remote ? "remote peer" : "us") + " Code: " + code + " Reason: " + reason);
        if (this.ws != null) {
//		    this.ws.close();
            this.ws = null;
        }
//        this.planes.clear();
//		this.plane_num = 0;
        Log.i("onClose", "onClose: " + reason);
        if (code == 1006) {
//            this.c.startSoc(this.c);
            //发送一个这种情况下，网络断了之后，需要自动重连的消息到mainaCITIVITY
            EventBus.getDefault().post(new DuanwangMessage(1, 1));

        }

    }

    @Override
    public void onError(Exception ex) {
        ex.printStackTrace();
        Log.i("onError", "onError: " + ex);
        // if the error is fatal then onClose will be called additionally
    }

    public void startSoc(PlayBackClient cs,String id) {
        this.id = id;
        c = cs;
        c.connect();


    }


}